package com.zhong.zxing.codescan;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Vector;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.zhong.zxing.R;
import com.zhong.zxing.camera.CameraManager;
import com.zhong.zxing.decoding.CaptureActivityHandler;
import com.zhong.zxing.decoding.InactivityTimer;
import com.zhong.zxing.view.ViewfinderView;

/**
 * Initial the camera
 * @author Ryan.Tang
 */
public class MipcaActivityCapture extends AppCompatActivity implements Callback, OnClickListener {

	private CaptureActivityHandler handler;
	private ViewfinderView viewfinderView;
	private boolean hasSurface;
	private Vector<BarcodeFormat> decodeFormats;
	private String characterSet;
	private InactivityTimer inactivityTimer;
	private MediaPlayer mediaPlayer;
	private boolean playBeep;
	private static final float BEEP_VOLUME = 0.10f;
	private boolean vibrate;


	/**
	 * 自定义的Path按钮动画的相关变量
	 */
	private ImageView m01;
	private ImageView m02;
	private ImageView m03;
	private ImageView m04;
	private ImageView m05;
	private ImageView m06;
	private boolean isOpened;
	private AnimatorSet mSet;
	private Animator mAnimator_other;
	private Animator mAnimator_other1;
	private Animator mAnimator_other2;
	private Animator mAnimator_other3;
	private Animator mTitle;
	private ObjectAnimator first;




	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_capture);
		//ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);
		CameraManager.init(getApplication());
		viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
		Toolbar toolbar = (Toolbar) findViewById(R.id.swap_toolbar);
		setSupportActionBar(toolbar);
		findViewById(R.id.swap_toolbar_back).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				MipcaActivityCapture.this.finish();
			}
		});
//		Button mButtonBack = (Button) findViewById(R.id.button_back);
//		mButtonBack.setOnClickListener(new OnClickListener() {
//
//			@Override
//			public void onClick(View v) {
//				MipcaActivityCapture.this.finish();
//
//			}
//		});

		//初始化自定义的Path按钮动画
		initView();
		hasSurface = false;
		inactivityTimer = new InactivityTimer(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
		SurfaceHolder surfaceHolder = surfaceView.getHolder();
		if (hasSurface) {
			initCamera(surfaceHolder);
		} else {
			surfaceHolder.addCallback(this);
			surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}
		decodeFormats = null;
		characterSet = null;

		playBeep = true;
		AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
		if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
			playBeep = false;
		}
		initBeepSound();
		vibrate = true;
		
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (handler != null) {
			handler.quitSynchronously();
			handler = null;
		}
		CameraManager.get().closeDriver();
	}

	@Override
	protected void onDestroy() {
		inactivityTimer.shutdown();

		super.onDestroy();
	}
	
	/**
	 * ����ɨ����
	 * @param result
	 * @param barcode
	 */
	public void handleDecode(Result result, Bitmap barcode) {
		inactivityTimer.onActivity();
		playBeepSoundAndVibrate();
		String resultString = result.getText();
		if (resultString.equals("")) {
			Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show();
		}else {
			Intent resultIntent = new Intent();
			Bundle bundle = new Bundle();
			bundle.putString("result", resultString);
//			bundle.putParcelable("bitmap", barcode);
			ByteArrayOutputStream baos=new ByteArrayOutputStream();
            barcode.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte [] bitmapByte =baos.toByteArray();
			bundle.putByteArray("bitmap",bitmapByte);
			resultIntent.putExtras(bundle);
			this.setResult(RESULT_OK, resultIntent);
		}
		MipcaActivityCapture.this.finish();
	}
	
	private void initCamera(SurfaceHolder surfaceHolder) {
		try {
			CameraManager.get().openDriver(surfaceHolder);
		} catch (IOException ioe) {
			return;
		} catch (RuntimeException e) {
			return;
		}
		if (handler == null) {
			handler = new CaptureActivityHandler(this, decodeFormats,
					characterSet);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if (!hasSurface) {
			hasSurface = true;
			initCamera(holder);
		}

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		hasSurface = false;

	}

	public ViewfinderView getViewfinderView() {
		return viewfinderView;
	}

	public Handler getHandler() {
		return handler;
	}

	public void drawViewfinder() {
		viewfinderView.drawViewfinder();

	}

	private void initBeepSound() {
		if (playBeep && mediaPlayer == null) {
			// The volume on STREAM_SYSTEM is not adjustable, and users found it
			// too loud,
			// so we now play on the music stream.
			setVolumeControlStream(AudioManager.STREAM_MUSIC);
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			mediaPlayer.setOnCompletionListener(beepListener);

			AssetFileDescriptor file = getResources().openRawResourceFd(
					R.raw.beep);
			try {
				mediaPlayer.setDataSource(file.getFileDescriptor(),
						file.getStartOffset(), file.getLength());
				file.close();
				mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
				mediaPlayer.prepare();
			} catch (IOException e) {
				mediaPlayer = null;
			}
		}
	}

	private static final long VIBRATE_DURATION = 200L;

	private void playBeepSoundAndVibrate() {
		if (playBeep && mediaPlayer != null) {
			mediaPlayer.start();
		}
		if (vibrate) {
			Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
			vibrator.vibrate(VIBRATE_DURATION);
		}
	}

	/**
	 * When the beep has finished playing, rewind to queue up another one.
	 */
	private final OnCompletionListener beepListener = new OnCompletionListener() {
		public void onCompletion(MediaPlayer mediaPlayer) {
			mediaPlayer.seekTo(0);
		}
	};


	/**
	 * 自定义的Path按钮动画
	 */
	private void initView() {
		m01 = (ImageView) findViewById(R.id.mainMenu01);
		m02 = (ImageView) findViewById(R.id.mainMenu02);
		m03 = (ImageView) findViewById(R.id.mainMenu03);
		m04 =  (ImageView) findViewById(R.id.mainMenu04);
		m05 = (ImageView) findViewById(R.id.mainMenu05);
		m06 =  (ImageView) findViewById(R.id.mainMenu06);

		m01.setOnClickListener(this);
		m02.setOnClickListener(this);
		m03.setOnClickListener(this);
		m04.setOnClickListener(this);
		m05.setOnClickListener(this);
		m06.setOnClickListener(this);
	}

	private void initAn() {
		mAnimator_other = AnimatorInflater.loadAnimator(this, R.animator.animator_show_other);
		mAnimator_other1 = AnimatorInflater.loadAnimator(this, R.animator.animator_show_other);
		mAnimator_other2 = AnimatorInflater.loadAnimator(this, R.animator.animator_show_other);
		mAnimator_other3 = AnimatorInflater.loadAnimator(this, R.animator.animator_show_other);
		mTitle = AnimatorInflater.loadAnimator(this, R.animator.animator_show_title);
		mSet = new AnimatorSet();
	}

	@Override
	public void onClick(View v) {
		int i = v.getId();
		if (i == R.id.mainMenu01) {
			if (!isOpened) {

				AnimatorSet set = new AnimatorSet();

				ObjectAnimator m01_animator = ObjectAnimator.ofFloat(
						m01,
						"rotation",
						0,
						-135)
						.setDuration(1000);

				ObjectAnimator m02_animation01 = ObjectAnimator.ofFloat(
						m02,
						"Y",
						m01.getY(),
						m01.getY() - 700)
						.setDuration(1100);

				ObjectAnimator m02_animation02 = ObjectAnimator.ofFloat(
						m02,
						"alpha",
						0,
						1)
						.setDuration(1100);

				ObjectAnimator m02_animation03 = ObjectAnimator.ofFloat(
						m02,
						"ScaleX",
						1f,
						1.5f)
						.setDuration(1100);

				ObjectAnimator m02_animation04 = ObjectAnimator.ofFloat(
						m02,
						"ScaleY",
						1f,
						1.5f)
						.setDuration(1100);

				ObjectAnimator m02_animation05 = ObjectAnimator.ofFloat(
						m02,
						"rotation",
						0,
						1800)
						.setDuration(1100);

				float v3 = (float) (700 * Math.sin(2 * Math.PI / 360 * 67.5));
				float v1 = m01.getY() - v3;
				ObjectAnimator m03_animation01 = ObjectAnimator.ofFloat(
						m03,
						"Y",
						m01.getY(),
						v1)
						.setDuration(1200);

				ObjectAnimator m03_animation02 = ObjectAnimator.ofFloat(
						m03,
						"alpha",
						0,
						1)
						.setDuration(1200);

				ObjectAnimator m03_animation03 = ObjectAnimator.ofFloat(
						m03,
						"ScaleX",
						1f,
						1.5f)
						.setDuration(1200);

				ObjectAnimator m03_animation04 = ObjectAnimator.ofFloat(
						m03,
						"ScaleY",
						1f,
						1.5f)
						.setDuration(1200);

				ObjectAnimator m03_animation05 = ObjectAnimator.ofFloat(
						m03,
						"rotation",
						0,
						1800)
						.setDuration(1200);

				float v2 = m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 67.5)));
				ObjectAnimator m03_animation06 = ObjectAnimator.ofFloat(
						m03,
						"X",
						m01.getX(),
						v2)
						.setDuration(1200);

				ObjectAnimator m04_animation01 = ObjectAnimator.ofFloat(
						m04,
						"Y",
						m01.getY(),
						m01.getY() - ((float) (700 * Math.sin(2 * Math.PI / 360 * 45))))
						.setDuration(1300);

				ObjectAnimator m04_animation02 = ObjectAnimator.ofFloat(
						m04,
						"alpha",
						0,
						1)
						.setDuration(1300);

				ObjectAnimator m04_animation03 = ObjectAnimator.ofFloat(
						m04,
						"ScaleX",
						1f,
						1.5f)
						.setDuration(1300);

				ObjectAnimator m04_animation04 = ObjectAnimator.ofFloat(
						m04,
						"ScaleY",
						1f,
						1.5f)
						.setDuration(1300);

				ObjectAnimator m04_animation05 = ObjectAnimator.ofFloat(
						m04,
						"rotation",
						0,
						1800)
						.setDuration(1300);

				ObjectAnimator m04_animation06 = ObjectAnimator.ofFloat(
						m04,
						"X",
						m01.getX(),
						m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 45))))
						.setDuration(1300);

				ObjectAnimator m05_animation01 = ObjectAnimator.ofFloat(
						m05,
						"Y",
						m01.getY(),
						m01.getY() - ((float) (700 * Math.sin(2 * Math.PI / 360 * 22.5))))
						.setDuration(1400);

				ObjectAnimator m05_animation02 = ObjectAnimator.ofFloat(
						m05,
						"alpha",
						0,
						1)
						.setDuration(1400);

				ObjectAnimator m05_animation03 = ObjectAnimator.ofFloat(
						m05,
						"ScaleX",
						1f,
						1.5f)
						.setDuration(1400);

				ObjectAnimator m05_animation04 = ObjectAnimator.ofFloat(
						m05,
						"ScaleY",
						1f,
						1.5f)
						.setDuration(1400);

				ObjectAnimator m05_animation05 = ObjectAnimator.ofFloat(
						m05,
						"rotation",
						0,
						1800)
						.setDuration(1400);

				ObjectAnimator m05_animation06 = ObjectAnimator.ofFloat(
						m05,
						"X",
						m01.getX(),
						m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 22.5))))
						.setDuration(1400);

				ObjectAnimator m06_animation01 = ObjectAnimator.ofFloat(
						m06,
						"X",
						m01.getX(),
						m01.getX() + 700)
						.setDuration(1500);

				ObjectAnimator m06_animation02 = ObjectAnimator.ofFloat(
						m06,
						"alpha",
						0,
						1)
						.setDuration(1500);

				ObjectAnimator m06_animation03 = ObjectAnimator.ofFloat(
						m06,
						"ScaleX",
						1f,
						1.5f)
						.setDuration(1500);

				ObjectAnimator m06_animation04 = ObjectAnimator.ofFloat(
						m06,
						"ScaleY",
						1f,
						1.5f)
						.setDuration(1500);

				ObjectAnimator m06_animation05 = ObjectAnimator.ofFloat(
						m06,
						"rotation",
						0,
						1800)
						.setDuration(1500);

				set.playTogether(
						m01_animator,
						m02_animation01,
						m02_animation02,
						m02_animation03,
						m02_animation04,
						m02_animation05,
						m03_animation01,
						m03_animation02,
						m03_animation03,
						m03_animation04,
						m03_animation05,
						m03_animation06,
						m04_animation01,
						m04_animation02,
						m04_animation03,
						m04_animation04,
						m04_animation05,
						m04_animation06,
						m05_animation01,
						m05_animation02,
						m05_animation03,
						m05_animation04,
						m05_animation05,
						m05_animation06,
						m06_animation01,
						m06_animation02,
						m06_animation03,
						m06_animation04,
						m06_animation05);

				set.start();

				isOpened = true;

			} else {

				AnimatorSet set = new AnimatorSet();

				ObjectAnimator m01_animator = ObjectAnimator.ofFloat(
						m01,
						"rotation",
						-135,
						0)
						.setDuration(1500);
				ObjectAnimator m02_animation01 = ObjectAnimator.ofFloat(
						m02,
						"Y",
						m01.getY() - 700,
						m01.getY())
						.setDuration(1400);

				ObjectAnimator m02_animation02 = ObjectAnimator.ofFloat(
						m02,
						"alpha",
						1,
						0)
						.setDuration(1400);

				ObjectAnimator m02_animation03 = ObjectAnimator.ofFloat(
						m02,
						"ScaleX",
						1.5f,
						1f)
						.setDuration(1400);

				ObjectAnimator m02_animation04 = ObjectAnimator.ofFloat(
						m02,
						"ScaleY",
						1.5f,
						1f)
						.setDuration(1400);

				ObjectAnimator m02_animation05 = ObjectAnimator.ofFloat(
						m02,
						"rotation",
						0,
						1800)
						.setDuration(1400);

				ObjectAnimator m03_animation01 = ObjectAnimator.ofFloat(
						m03,
						"Y",
						m01.getY() - ((float) (700 * Math.sin(2 * Math.PI / 360 * 67.5))),
						m01.getY())
						.setDuration(1300);

				ObjectAnimator m03_animation02 = ObjectAnimator.ofFloat(
						m03,
						"alpha",
						1,
						0)
						.setDuration(1300);

				ObjectAnimator m03_animation03 = ObjectAnimator.ofFloat(
						m03,
						"ScaleX",
						1.5f,
						1f)
						.setDuration(1300);

				ObjectAnimator m03_animation04 = ObjectAnimator.ofFloat(
						m03,
						"ScaleY",
						1.5f,
						1f)
						.setDuration(1300);

				ObjectAnimator m03_animation05 = ObjectAnimator.ofFloat(
						m03,
						"rotation",
						1800,
						0)
						.setDuration(1300);

				ObjectAnimator m03_animation06 = ObjectAnimator.ofFloat(
						m03,
						"X",
						m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 67.5))),
						m01.getX())
						.setDuration(1300);

				ObjectAnimator m04_animation01 = ObjectAnimator.ofFloat(
						m04,
						"Y",
						m01.getY() - ((float) (700 * Math.sin(2 * Math.PI / 360 * 45))),
						m01.getY())
						.setDuration(1200);

				ObjectAnimator m04_animation02 = ObjectAnimator.ofFloat(
						m04,
						"alpha",
						1,
						0)
						.setDuration(1200);

				ObjectAnimator m04_animation03 = ObjectAnimator.ofFloat(
						m04,
						"ScaleX",
						1.5f,
						1f)
						.setDuration(1200);

				ObjectAnimator m04_animation04 = ObjectAnimator.ofFloat(
						m04,
						"ScaleY",
						1.5f,
						1f)
						.setDuration(1200);

				ObjectAnimator m04_animation05 = ObjectAnimator.ofFloat(
						m04,
						"rotation",
						1800,
						0)
						.setDuration(1200);

				ObjectAnimator m04_animation06 = ObjectAnimator.ofFloat(
						m04,
						"X",
						m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 45))),
						m01.getX())
						.setDuration(1200);

				ObjectAnimator m05_animation01 = ObjectAnimator.ofFloat(
						m05,
						"Y",
						m01.getY() - ((float) (700 * Math.sin(2 * Math.PI / 360 * 22.5))),
						m01.getY())
						.setDuration(1100);

				ObjectAnimator m05_animation02 = ObjectAnimator.ofFloat(
						m05,
						"alpha",
						1,
						0)
						.setDuration(1100);

				ObjectAnimator m05_animation03 = ObjectAnimator.ofFloat(
						m05,
						"ScaleX",
						1.5f,
						1f)
						.setDuration(1100);

				ObjectAnimator m05_animation04 = ObjectAnimator.ofFloat(
						m05,
						"ScaleY",
						1.5f,
						1f)
						.setDuration(1100);

				ObjectAnimator m05_animation05 = ObjectAnimator.ofFloat(
						m05,
						"rotation",
						1800,
						0)
						.setDuration(1100);

				ObjectAnimator m05_animation06 = ObjectAnimator.ofFloat(
						m05,
						"X",
						m01.getX() + ((float) (700 * Math.cos(2 * Math.PI / 360 * 22.5))),
						m01.getX())
						.setDuration(1100);

				ObjectAnimator m06_animation01 = ObjectAnimator.ofFloat(
						m06,
						"X",
						m01.getX() + 700,
						m01.getX())
						.setDuration(1000);

				ObjectAnimator m06_animation02 = ObjectAnimator.ofFloat(
						m06,
						"alpha",
						1,
						0)
						.setDuration(1000);

				ObjectAnimator m06_animation03 = ObjectAnimator.ofFloat(
						m06,
						"ScaleX",
						1.5f,
						1f)
						.setDuration(1000);

				ObjectAnimator m06_animation04 = ObjectAnimator.ofFloat(
						m06,
						"ScaleY",
						1.5f,
						1f)
						.setDuration(1000);

				ObjectAnimator m06_animation05 = ObjectAnimator.ofFloat(
						m06,
						"rotation",
						0,
						1800)
						.setDuration(1000);

				set.playTogether(
						m01_animator,
						m02_animation01,
						m02_animation02,
						m02_animation03,
						m02_animation04,
						m02_animation05,
						m03_animation01,
						m03_animation02,
						m03_animation03,
						m03_animation04,
						m03_animation05,
						m03_animation06,
						m04_animation01,
						m04_animation02,
						m04_animation03,
						m04_animation04,
						m04_animation05,
						m04_animation06,
						m05_animation01,
						m05_animation02,
						m05_animation03,
						m05_animation04,
						m05_animation05,
						m05_animation06,
						m06_animation01,
						m06_animation02,
						m06_animation03,
						m06_animation04,
						m06_animation05);

				set.start();

				isOpened = false;

			}

		} else if (i == R.id.mainMenu02) {
			initAn();
			first = getMFirst();
			mTitle.setTarget(m02);
			mAnimator_other.setTarget(m03);
			mAnimator_other1.setTarget(m04);
			mAnimator_other2.setTarget(m05);
			mAnimator_other3.setTarget(m06);
			mSet.playTogether(first, mTitle, mAnimator_other, mAnimator_other1, mAnimator_other2, mAnimator_other3);
			mSet.start();
			toReInit();
			isOpened = false;
			new Handler().postDelayed(new Runnable() {
				@Override
				public void run() {
					MipcaActivityCapture.this.finish();
				}
			}, 1500);

		} else if (i == R.id.mainMenu03) {
			initAn();
			first = getMFirst();
			mTitle.setTarget(m03);
			mAnimator_other.setTarget(m02);
			mAnimator_other1.setTarget(m04);
			mAnimator_other2.setTarget(m05);
			mAnimator_other3.setTarget(m06);
			mSet.playTogether(first, mTitle, mAnimator_other, mAnimator_other1, mAnimator_other2, mAnimator_other3);
			mSet.start();
			toReInit();
			isOpened = false;


		} else if (i == R.id.mainMenu04) {
			initAn();
			first = getMFirst();
			mTitle.setTarget(m04);
			mAnimator_other.setTarget(m03);
			mAnimator_other1.setTarget(m02);
			mAnimator_other2.setTarget(m06);
			mAnimator_other3.setTarget(m05);
			mSet.playTogether(first, mTitle, mAnimator_other, mAnimator_other1, mAnimator_other2, mAnimator_other3);
			mSet.start();
			toReInit();
			isOpened = false;


		} else if (i == R.id.mainMenu05) {
			initAn();
			first = getMFirst();
			mSet = new AnimatorSet();
			mTitle.setTarget(m05);
			mAnimator_other.setTarget(m03);
			mAnimator_other1.setTarget(m04);
			mAnimator_other2.setTarget(m06);
			mAnimator_other3.setTarget(m02);
			mSet.playTogether(first, mTitle, mAnimator_other, mAnimator_other1, mAnimator_other2, mAnimator_other3);
			mSet.start();
			toReInit();
			isOpened = false;


		} else if (i == R.id.mainMenu06) {
			initAn();
			first = getMFirst();
			mTitle.setTarget(m06);
			mAnimator_other.setTarget(m03);
			mAnimator_other1.setTarget(m04);
			mAnimator_other2.setTarget(m05);
			mAnimator_other3.setTarget(m02);
			mSet.playTogether(first, mTitle, mAnimator_other, mAnimator_other1, mAnimator_other2, mAnimator_other3);
			mSet.start();
			toReInit();
			isOpened = false;


		}
	}

	private ObjectAnimator getMFirst() {
		ObjectAnimator m01_animator = ObjectAnimator.ofFloat(
				m01,
				"rotation",
				-135,
				0)
				.setDuration(1500);

		return m01_animator;
	}

	private void toReInit(){

		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() {
				m02.setY(m01.getY());
				m02.setX(m01.getX());
				m03.setY(m01.getY());
				m03.setX(m01.getX());
				m04.setY(m01.getY());
				m04.setX(m01.getX());
				m05.setY(m01.getY());
				m05.setX(m01.getX());
				m06.setY(m01.getY());
				m06.setX(m01.getX());
			}
		}, 1000);

	}
}